/*
 * Copyright (c) 2020 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <securec.h>
#include <unistd.h>
#include <pthread.h>
#include "ohos_errno.h"
#include "ohos_types.h"
#include "hal_token.h"

#include "lsoh_nvmem_io.h"
#include "hal_token_const_var.h"

#define HAL_TOKEN_OK (0)
#define HAL_TOKEN_ERR (-1)

pthread_mutex_t tokenMutex = PTHREAD_MUTEX_INITIALIZER; // 创建互斥锁

static int HalTokenIOLenMatch(nv_var_type var_type, unsigned int len)
{
    int var_len;
    var_len = get_nv_var_size(var_type);
    // 当作字符串看待，要考虑最后一个 \0
    return (var_len + 1 == len);
}

int HalReadToken(char *token, unsigned int len)
{
    int res;
    int tokenLock;
    unsigned char* temp = NULL;
    if (token == NULL) {
        return EC_FAILURE;
    }
    if (!HalTokenIOLenMatch(NV_TYPE_TOKEN, len)) {
        return EC_FAILURE;
    }
    res = 1;
    tokenLock = pthread_mutex_lock(&tokenMutex);
    if (tokenLock == 0) {
        res = nv_var_read(NV_TYPE_TOKEN, &temp);
        pthread_mutex_unlock(&tokenMutex);
    }
    if (temp) {
        memcpy_s(token, len - 1, temp, len - 1);
        token[len - 1] = '\0';
        free(temp);
        temp = NULL;
    }
    return res ? HAL_TOKEN_ERR : HAL_TOKEN_OK;
}

int HalWriteToken(const char *token, unsigned int len)
{
    int res;
    int tokenLock;
    if (token == NULL) {
        return EC_FAILURE;
    }
    if (!HalTokenIOLenMatch(NV_TYPE_TOKEN, len)) {
        return EC_FAILURE;
    }
    res = 1;
    tokenLock = pthread_mutex_lock(&tokenMutex);
    if (tokenLock == 0) {
        res = nv_var_write(NV_TYPE_TOKEN, token);
        pthread_mutex_unlock(&tokenMutex);
    }
    return res ? HAL_TOKEN_ERR : HAL_TOKEN_OK;
}

int HalGetAcKey(char *acKey, unsigned int len)
{
    if ((acKey == NULL) || (len == 0)) {
        return EC_FAILURE;
    }
    const char manufacturekeyBuf[] = MANU_KEY;
    uint32_t manufacturekeyBufLen = sizeof(manufacturekeyBuf);
    if (len < manufacturekeyBufLen) {
        return EC_FAILURE;
    }

    int ret = memcpy_s(acKey, len, manufacturekeyBuf, manufacturekeyBufLen);
    return ret;
}

int HalGetProdId(char *productId, unsigned int len)
{
    if ((productId == NULL) || (len == 0)) {
        return EC_FAILURE;
    }
    const char productIdBuf[] = PROD_ID; //"OH00000D";
    uint32_t productIdLen = strlen(productIdBuf);
    if (len < productIdLen) {
        return EC_FAILURE;
    }

    int ret = memcpy_s(productId, len, productIdBuf, productIdLen);
    return ret;
}

int HalGetProdKey(char *productKey, unsigned int len)
{
    if ((productKey == NULL) || (len == 0)) {
        return EC_FAILURE;
    }
    const char productKeyBuf[] = "test";
    uint32_t productKeyLen = sizeof(productKeyBuf);
    if (len < productKeyLen) {
        return EC_FAILURE;
    }

    int ret = memcpy_s(productKey, len, productKeyBuf, productKeyLen);
    return ret;
}